/*
 *  This file is part of Bracket Properties
 *  Copyright 2011-2013 David R. Smith
 *  All Rights Reserved
 *
 */
package asia.redact.bracket.properties.serializer;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import asia.redact.bracket.properties.Properties;

/**
 * Encapsulate class name handling so that it is serialized more compactly (no duplicated package names).
 * 
 * @author Dave
 *
 */
public class PackageMap {

	private List<String> packages;
	public final String PACKAGE_ROOT_KEY = "packages";
	Pattern CLASS_PARAM_PAT = Pattern.compile("\\$(\\d+)(\\.[a-zA-Z0-9]+)");
	
	public PackageMap() {
		packages = new ArrayList<String>();
	}
	
	public int addPackage(Class<?> cls) {
		if(cls.getPackage() == null) return -1;
		String name = cls.getPackage().getName();
		if(packages.contains(name)){
			return packages.lastIndexOf(name);
		}else {
			packages.add(name);
			return packages.lastIndexOf(name);
		}
	}
	
	public void printToProperties(Properties props){
		for(int i= 0;i<packages.size();i++){
			props.put(PACKAGE_ROOT_KEY+"."+i, packages.get(i));
		}
	}
	
	public void loadFromProperties(Properties props){
		List<String> pkgs = props.getList(PACKAGE_ROOT_KEY);
		if(pkgs != null && pkgs.size() >0){
			packages.addAll(pkgs);
		}
	}
	
	public String valueAt(int index) {
		return packages.get(index);
	}
	
	public String classNameFor(String token) {
		if(token.startsWith("$")){
			// will be in the form $0.Name
			Matcher m = CLASS_PARAM_PAT.matcher(token);
			if(m.matches()){
				int val = Integer.parseInt(m.group(1));
				String end = m.group(2);
				String pkg = valueAt(val);
				return pkg+end;
			}else{
				throw new RuntimeException("Failed to match token: "+token);
			}
		}else{
			return token;
		}
		
	}
	
	public int size() {
		return packages.size();
	}

}
